//
// SoapTrace.Net - A soap message monitoring utility. 
//
// Copyright (C) 2004-2007 Matthew Ward
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
// Matthew Ward (mrward@users.sourceforge.net)

using SoapTrace.Core.Diagnostics;
using System;

namespace SoapTrace
{
	/// <summary>
	/// Monitors debug messages and displays the 
	/// <see cref="DebugMessagesForm"/> when requested.
	/// </summary>
	public class DebugMessageMonitor : IDisposable
	{
		/// <summary>
		/// Disposed flag.
		/// </summary>
		private bool m_Disposed;
		
		/// <summary>
		/// The default number of debug log messages to keep.
		/// </summary>
		public const int DefaultMessageLimit = 10;
		
		/// <summary>
		/// A collection of debug log entries.
		/// </summary>
		private LogEntryCollection m_LogEntries = new LogEntryCollection( );
		
		/// <summary>
		/// The debug messages form.
		/// </summary>
		private DebugMessagesForm m_DebugMessagesForm;
		
		/// <summary>
		/// Creates a new instance of the <see cref="DebugMessageMonitor"/>
		/// class.
		/// </summary>
		public DebugMessageMonitor( )
		{
			// Make sure we store some messages whilst we are starting up.
			m_LogEntries.CountLimit =  DebugMessageMonitor.DefaultMessageLimit;

			// Catch log events.
			Logger.LogEntryAdded += new LogEventHandler( OnLogEntryAdded );
		}
		
		/// <summary>
		/// Disposes this class.
		/// </summary>
		public void Dispose()
		{
			Dispose( true );

			GC.SuppressFinalize( this );
		}		
		
		/// <summary>
		/// Gets or sets the maximum number of messages to store for
		/// display purposes.
		/// </summary>
		public int MessageLimit
		{
			get
			{
				return m_LogEntries.CountLimit;
			}
			
			set
			{
				m_LogEntries.CountLimit = value;
			}
		}
		
		/// <summary>
		/// Gets or sets the log level.
		/// </summary>
		public LogLevel Level
		{
			get
			{
				return Logger.Level;
			}
			
			set
			{
				Logger.Level = value;
			}
		}
		
		/// <summary>
		/// Gets or sets whether to log bytes as a string.
		/// </summary>
		public bool LogBytesAsString
		{
			get
			{
				return Logger.LogBytesAsString;
			}
			
			set
			{
				Logger.LogBytesAsString = value;
			}
		}
		
		/// <summary>
		/// Shows the debug messages form.
		/// </summary>
		public void ShowDebugMessages( )
		{
			if( m_DebugMessagesForm == null )
			{
				m_DebugMessagesForm = new DebugMessagesForm( this );
				m_DebugMessagesForm.MessageLimit = m_LogEntries.CountLimit;
				m_DebugMessagesForm.Level = Logger.Level;
				
				m_DebugMessagesForm.Closed += new EventHandler( OnDebugMessagesFormClosed );
			
				m_DebugMessagesForm.Add( m_LogEntries );
			}
			
			m_DebugMessagesForm.Show( );	
		}
		
		/// <summary>
		/// Clears all saved log messages.
		/// </summary>
		public void Clear( )
		{
			m_LogEntries.Clear( );
			
			if( m_DebugMessagesForm != null )
			{
				m_DebugMessagesForm.Clear( );
			}
		}
		
		/// <summary>
		/// Handles the <see cref="Logger.LogEntryAdded"/> event.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="LogEventArgs"/> associated
		/// with this event.</param>
		private void OnLogEntryAdded( object sender, LogEventArgs e )
		{
			lock( m_LogEntries )
			{
				// Store the log event.
				m_LogEntries.Add( e.LogEntry );

				// Update the debug messages view if it is on display.
				if( m_DebugMessagesForm != null )
				{
					m_DebugMessagesForm.Add( e.LogEntry );
				}
			}
		}	
		
		/// <summary>
		/// The <see cref="DebugMessagesForm"/> has been closed.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The event arguments.</param>
		private void OnDebugMessagesFormClosed( object sender, EventArgs e )
		{
			lock( m_LogEntries )
			{
				// Save message limit because sometimes this will be changed
				// but not raise an event (e.g. if the number is typed in and the
				// user did not hit return.
				
				m_LogEntries.CountLimit = m_DebugMessagesForm.MessageLimit;
				
				m_DebugMessagesForm.Dispose( );
				m_DebugMessagesForm = null;
			}
		}
		
		/// <summary>
		/// Disposes managed and unmanaged objects. 
		/// </summary>
		/// <param name="disposing">If <see langword="true"/> the method has been called directly
		/// or indirectly by a user's code. Managed and unmanaged resources
		/// can be disposed.
		/// If disposing equals <see langword="false"/>, the method has been called by the 
		/// runtime from inside the finalizer and you should not reference 
		/// other objects. Only unmanaged resources can be disposed.
		/// </param>
		private void Dispose( bool disposing )
		{
			if( !m_Disposed )
			{
				if( disposing )
				{
					// Dispose managed resources.
					if( m_DebugMessagesForm != null )
					{
						m_DebugMessagesForm.Dispose( );
						m_DebugMessagesForm.Close( );
					}
				}
			}

			m_Disposed = true;         
		}
		
	}
}
